/*
 * Copyright (c) InContent.
 * Author: Val
 * Modified At: 16-3-15 下午2:22
 */

package org.alfalfa.datawarehouse;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import org.bson.Document;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;

/**
 * @Author : Val
 * @Created : 2015-10-12
 * @E-mail : valer@126.com
 * @Version : 1.0
 */
public class DWResultset {

	private MongoCollection<Document> collection;
	private Iterator<Document> it;
	FindIterable<Document> fi;

	public DWResultset(MongoCollection<Document> collection, FindIterable<Document> fi) {
		this.collection = collection;
		this.fi = fi;
		this.it = fi.iterator();
	}

	public DWRecord first() {
		Document document = fi.first();
		if (document == null) return null;
		return new DWRecord(collection, document);
	}

	public <T extends DWRecord> T first(Class<T> cls) {
		Document document = fi.first();
		if (document == null) return null;

		try {
			Constructor<T> c = cls.getDeclaredConstructor(MongoCollection.class, Document.class);
			c.setAccessible(true);
			return c.newInstance(collection, document);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return null;
	}

	public boolean next() {
		return it.hasNext();
	}

	public DWRecord get() {
		return new DWRecord(collection, it.next());
	}

	public <T extends DWRecord> T get(Class<T> cls) {
		try {
			Constructor<T> c = cls.getDeclaredConstructor(MongoCollection.class, Document.class);
			c.setAccessible(true);
			return c.newInstance(collection, it.next());
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return null;
	}

}
